package com.czk.rdd.operator.transform

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
 * @Author:ChenZhangKun
 * @Date: 2021/12/10 10:17
 */
object CombineKey{
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(("a", 1), ("a", 2), ("a", 3), ("a", 4),("b",5)), 2)
    // 最通用的对 key-value 型 rdd 进行聚集操作的聚集函数（aggregation function）。类似于
    // aggregate()，combineByKey()允许用户返回值的类型与输入不一致。
    val combineRdd: RDD[(String, (Int, Int))] = rdd.combineByKey(
      // 相同key的第一条数据处理函数，第一个值不会参与计算
      (_, 1),
      // 分区内数据的处理操作
      (acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
      // 分区间的数据处理操作
      (acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)
    )
    combineRdd.collect().foreach(println)
    sc.stop()
  }
}
